trappy
knows about some trace events. You can add your own in the notebook without having to change any code in trappy
. After the trace is registered, the next time you parse a trace file that information will be part of the trace object as a pandas DataFrame
and can be analyzed like the other DataFrame
s in the FTrace
class.
The trace event must follow the following format:
title: key0=value0 key1=value1 key2=value2 ...
The title should be something that's unique in the trace. For example, you can generate trace with the following trace_printk()
:
trace_printk("thermal_gpu_power_get: frequency=%u load=%d\n", freq, load);
which will appear in the trace.txt
as:
kworker/6:1-457 [006] 144.439566: bprint: 0xc042f8a0f: thermal_gpu_power_get: frequency=177 load=0
You can add this event to the trace instance using register_dynamic_ftrace()
First import trappy
In [1]:
import sys
sys.path.append("..")
%matplotlib inline
import trappy
Register it. The first argument is the name under which you will find it in the trace instance. It will be changed to lower_case_with_underscores_to_separate_words. The second argument is some unique text in the trace, usually the title:
In [2]:
trappy.register_dynamic_ftrace("gpu_power_in", "thermal_gpu_power_get")
Out[2]:
Now we can parse the trace
In [3]:
trace = trappy.FTrace("/path/to/trace")
trace
now has a gpu_power_in
member that contains the information. We can see the first few lines of the generated dataframe:
In [5]:
trace.gpu_power_in.data_frame.head()
Out[5]:
We can now plot it or manipulate it as any other DataFrame
in pandas
In [8]:
figsize(18, 7)
trace.gpu_power_in.data_frame["frequency"].plot()
Out[8]:
register_dynamic_ftrace()
is useful for simple traces in which you don't need to do any post-processing. If you need to register a full-featured trace class you can use trappy.register_ftrace_parser()
for this. For example, a class that parses trace for capacity_per_group:
and wants to limit the cpumasks to 8-digit could declare it like this:
In [8]:
from trappy.base import Base
class GroupCapacity(Base):
unique_word = "capacity_per_group:"
name = "group_capacity"
_cpus_column = "cpus"
def __init__(self):
super(GroupCapacity, self).__init__(
unique_word=self.unique_word,
)
def finalize_object(self):
if self._cpus_column in self.data_frame.columns:
self.data_frame[self._cpus_column] = self.data_frame[self._cpus_column].apply('{:0>8}'.format)
trappy.register_ftrace_parser(GroupCapacity)
Now after parsing your trace using trappy.FTrace()
you can access it's group_capacity member. For example:
trappy.LinePlot(trace, GroupCapacity, column="group_capacity", pivot="cpus", marker='.', linestyle='none', per_line=2).view()